package com.xunshibao.core.db;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.junit.Test;

public class EntityGenerator {
    static {
        try {
            Class.forName("org.gjt.mm.mysql.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    private Connection getConnection() {
        try {
            String url = "jdbc:mysql://localhost:3306/salary?useUnicode=true&amp;characterEncoding=utf-8";
            Connection conn = DriverManager.getConnection(url, "root", "123456");
            return conn;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public Map<String, TableBean> tbMap = new HashMap<String, TableBean>();

    public Map<String, List<FieldBean>> getSchema() throws Exception {
        Map<String, List<FieldBean>> tableMap = new HashMap<String, List<FieldBean>>();
        List<FieldBean> fields;
        List<TableBean> tables = getTables();
        Connection conn = getConnection();
        PreparedStatement pstmt;
        for (TableBean table : tables) {
            fields = new ArrayList<FieldBean>();
            tableMap.put(table.name, fields);
            tbMap.put(table.name, table);
            String query = "show full fields from {0}";
            // String tableName = "c_school";
            query = query.replace("{0}", table.name);

            pstmt = conn.prepareStatement(query);
            pstmt.execute();
            ResultSet rs = pstmt.getResultSet();
            FieldBean bean;
            while (rs.next()) {
                bean = new FieldBean();
                bean.name = rs.getString(1);
                bean.type = rs.getString(2);
                bean.comment = rs.getString(9);
                fields.add(bean);
            }
            rs.close();
            pstmt.close();
        }
        conn.close();

        return tableMap;
    }

    public List<TableBean> getTables() throws Exception {
        List<TableBean> result = new ArrayList<TableBean>();
        // String query = "show tables";
        String query = "SHOW TABLE status";
        TableBean bean;
        Connection conn = getConnection();
        PreparedStatement pstmt = conn.prepareStatement(query);
        pstmt.execute();
        ResultSet rs = pstmt.getResultSet();
        while (rs.next()) {
            bean = new TableBean();
            bean.comment = rs.getString("comment");
            bean.name = rs.getString(1);
            result.add(bean);
        }
        rs.close();
        pstmt.close();
        conn.close();

        return result;
    }

    @Test
    public void mainJen() {
        try {
            genJava(getSchema(), "com.eonezhang.oa.salary.po");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Map<String, String> getTableClassMapping() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("attendanceinfo", "AttendanceInfo");
        map.put("leaverecord", "LeaveRecord");
        map.put("salaryinfo", "SalaryInfo");

        map.put("workingday", "WarkingDay");
        map.put("othersalary", "OtherSalary");

        map.put("employee", "Employee");
        map.put("holiday", "Holiday");
        map.put("social", "Social");
        map.put("wage", "Wage");

        return map;
    }

    public void genJava(Map<String, List<FieldBean>> tables, String packageName) throws Exception {
        Map<String, String> mapping = getTableClassMapping();
        Set<Map.Entry<String, List<FieldBean>>> entry = tables.entrySet();
        Iterator<Entry<String, List<FieldBean>>> iter = entry.iterator();
        Entry<String, List<FieldBean>> en;
        String key;
        List<FieldBean> beans;
        File dir = new File("gen");
        if (!dir.exists()) {
            dir.mkdirs();
        }
        BufferedWriter buf = null;
        String className = null;
        TableBean tbean;
        while (iter.hasNext()) {
            en = iter.next();
            key = en.getKey();
            tbean = tbMap.get(key);
            if (mapping.containsKey(key)) {
                className = mapping.get(key);
            } else {
                className = key.substring(2, 3).toUpperCase() + key.substring(3);
            }
            buf = new BufferedWriter(new FileWriter(new File(dir, className + ".java")));

            buf.append("package ");
            buf.append(packageName);
            buf.append(";\n/**\n");
            buf.append(tbean.comment.split(";")[0]);
            buf.append('\n');
            buf.append("* @author eonezhang\n");
            buf.append("*/\n public class ");
            buf.append(className);
            buf.append(" {\npublic static final String TB=\"");
            buf.append(key);
            buf.append("\";\n");
            beans = en.getValue();
            for (FieldBean b : beans) {
                buf.append("/**");
                buf.append(b.getComment());
                buf.append("*/\n");
                buf.append("private ");
                buf.append(b.getType());
                buf.append(" ");
                buf.append(b.getName().toLowerCase());
                buf.append(";\n");

                // getter
                buf.append("/**\n获取\t");
                buf.append(b.getComment());
                buf.append("\n@return ");
                buf.append(b.getComment());
                buf.append("*/\n");
                buf.append("public ");
                buf.append(b.getType());
                buf.append(" get");
                buf.append(b.getName().toUpperCase().substring(0, 1));
                buf.append(b.getName().toLowerCase().substring(1));
                buf.append("(){\n return ");
                buf.append(b.getName().toLowerCase());
                buf.append(";\n}\n");
                // setter

                buf.append("/**设置\t");
                buf.append(b.getComment());
                buf.append("\n@param ");
                buf.append(b.getName().toLowerCase());
                buf.append("\t");
                buf.append(b.getComment());
                buf.append("*/\n");
                buf.append("public void ");
                buf.append(" set");
                buf.append(b.getName().toUpperCase().substring(0, 1));
                buf.append(b.getName().toLowerCase().substring(1));
                buf.append("(");
                buf.append(b.getType());
                buf.append(" ");
                buf.append(b.getName().toLowerCase());
                buf.append(") {\nthis.");
                buf.append(b.getName().toLowerCase());
                buf.append("=");
                buf.append(b.getName().toLowerCase());
                buf.append(";\n}\n");
            }

            buf.append(" }");
            buf.flush();
            buf.close();
        }
    }
}

class TableBean {
    String name;
    String comment;
}

class FieldBean {
    Map<String, String> typeMapping = new HashMap<String, String>();
    String name;
    String type;
    String comment;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getComment() {
        return comment.replaceAll("\t", "\0");
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public String getType() {
        if (type.indexOf("bigint") != -1) {
            return "Long";
        } else if (type.indexOf("int") != -1) {
            return "Integer";
        } else if (type.indexOf("char") != -1) {
            return "String";
        } else if (type.indexOf("date") != -1) {
            return "Date";
        } else if (type.indexOf("bool") != -1) {
            return "Boolean";
        } else if (type.indexOf("decimal") != -1) {
            return "BigDecimal";
        }
        return null;
    }

}
